#pragma once
// 25
#include "noncopyable.h"
#include <functional>
#include <vector>
#include <atomic>
#include "Timestamp.h"
#include <memory>
#include <mutex>
#include "CurrentThread.h"

class Channel;
class Poller;
// one loop per thread
//事件循环类，主要包含Channel 和 Poller(epoll poll 抽象)
class EventLoop : noncopyable {
    public:
        using Functor = std::function<void()>;
        EventLoop();
        ~EventLoop();

        // 开启事件循环
        void loop();
        // 退出事件循环
        void quit();

        Timestamp pollReturnTime() const { return pollReturnTime_; }
        // 在当前线程执行cb
        void runInLoop(Functor cb);
        // 把cb放入队列中，唤醒loop所在的线程执行cb
        void queueInLoop(Functor cb);

        // 唤醒loop所在线程
        void wakeup(); // main reactor唤醒 sub reactor, 往Wakeupfd写来唤醒
        
        // eventloop的方法调用poller的方法
        void updateChannel(Channel* channel);
        void removeChannel(Channel* channel);
        bool hasChannel(Channel* channel);

        // 判断eventloop对象是否在自己的线程中
        bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }

    private:
        void handleRead(); //waked up
        void doPendingFunctors(); //执行回调

        using ChannelList = std::vector<Channel*>;
        std::atomic_bool looping_;
        std::atomic_bool quit_; //标志退出loop循环

        
        const pid_t threadId_;
        Timestamp pollReturnTime_;//poller返回发生事件的channels的时间
        std::unique_ptr<Poller> poller_; //组合
        int wakeupFd_; //主要作用，当mainloop获取一个新用户的channel，通过轮询算法选择一个subloop，通过该成员唤醒subloop处理事件
        std::unique_ptr<Channel> wakeupChannel_;

        ChannelList activeChannels_; // 存放发生事件的channel集合，通过Poller获得
        //Channel* currentActiveChannel_;

        std::atomic_bool callingPendingFunctors_;//标识当前loop是否有需要执行的回调操作
        
        std::vector<Functor> pendingFunctors_;//存储loop需要执行的所有回调操作
        std::mutex mutex_; // 互斥锁用来保护上面vector的线程安全操作

};